//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

namespace Eas.WebCrawler.Test.Scenario {
    public interface TestEventHandler {
        void AfterStop(object sender, EventArgs args);
        void AfterPause(object sender, EventArgs args);
        void BeforeStart(object sender, EventArgs args);
        void BeforeUnPause(object sender, EventArgs args);

        void Trace(object sender, Eas.WebCrawler.Interfaces.ProcessingStateMessageEventArgs args);
        void Error(object sender, Eas.WebCrawler.Interfaces.ProcessingStateMessageEventArgs args);
        void UrlProcessed(object sender, Eas.WebCrawler.Interfaces.UrlCompletedEventArgs args);
        void UrlFailed(object sender, Eas.WebCrawler.Interfaces.UrlFailedEventArgs args);
        void UrlProcessingBegan(object sender, Eas.WebCrawler.Interfaces.ProcessingStateEventArgs args);
    }

    internal static class TestHelper {
        private const string TestFileName = "history.txt";

        public static void AddToHistoryFile(Eas.WebCrawler.Common.Test.TestDirectory directory, string uri) {
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(directory.CreateFileName(TestFileName), true)) {
                writer.WriteLine(directory.CreateFileName(uri));
            }
        }

        public static Eas.WebCrawler.Interfaces.WebCrawlerEngine CreateEngine(Eas.WebCrawler.Model.Gateway.WebGateway gateway, TestEventHandler handler, Eas.WebCrawler.Common.Test.TestDirectory directory, int workerCount, int timeout, params string[] startingUris) {
            TestSettings settings = new TestSettings();
            settings.CompletedRequestHistory.Dispose();
            settings.SleepTimeInMilliseconds = 25;
            settings.StartingUris = startingUris;
            settings.WorkerCount = workerCount;
            settings.StorageFactory = new Eas.WebCrawler.PlugIns.TemporaryStorage.MemoryStorageFactory();
            settings.Selector = new Eas.WebCrawler.PlugIns.Selectors.MaximumDepthSelector(3, new Eas.WebCrawler.PlugIns.Selectors.ConstantSelector(true));
            settings.RequestPriorityComparer = new Eas.WebCrawler.PlugIns.RequestComparers.AlphabeticComparer();
            settings.LinkExtractor = new Eas.WebCrawler.PlugIns.LinkExtractors.HtmlLinkExtractor();
            settings.CompletedRequestHistory = new Eas.WebCrawler.PlugIns.Histories.FileBasedRequestHistory(directory.CreateFileName(TestFileName));
            settings.TimeoutInMilliseconds = timeout;


            Eas.WebCrawler.Interfaces.WebCrawlerEngine engine = null;
            if (gateway == null) {
                engine = Eas.WebCrawler.Model.WebCrawlerFactory.Create(settings);
            }
            else {
                engine = Eas.WebCrawler.Model.WebCrawlerFactory.Create(settings, gateway, new Eas.WebCrawler.Model.Actions.BaseActionFactory());
            }

            engine.Events.Paused += new EventHandler(handler.AfterPause);
            engine.Events.Unpausing += new EventHandler(handler.BeforeUnPause);
            engine.Events.Stopped += new EventHandler(handler.AfterStop);
            engine.Events.Starting += new EventHandler(handler.BeforeStart);

            engine.Events.OnTrace += new EventHandler<Eas.WebCrawler.Interfaces.ProcessingStateMessageEventArgs>(handler.Trace);
            engine.Events.OnError += new EventHandler<Eas.WebCrawler.Interfaces.ProcessingStateMessageEventArgs>(handler.Error);

            engine.Events.UrlProcessed += new EventHandler<Eas.WebCrawler.Interfaces.UrlCompletedEventArgs>(handler.UrlProcessed);
            engine.Events.UrlFailed += new EventHandler<Eas.WebCrawler.Interfaces.UrlFailedEventArgs>(handler.UrlFailed);
            engine.Events.UrlBeganProcessing += new EventHandler<Eas.WebCrawler.Interfaces.ProcessingStateEventArgs>(handler.UrlProcessingBegan);

            return engine;
        }

        public static void ExpectUrlProcessed(Eas.WebCrawler.Model.Core.BaseProcessingState state, TestEventHandler handler, NMock2.IAction action) {
            if (action == null)
                NMock2.Expect.Once.On(handler).Method("UrlProcessed").With(new Eas.WebCrawler.Interfaces.UrlCompletedEventArgs(state, state.ResponseStore));
            else
                NMock2.Expect.Once.On(handler).Method("UrlProcessed").With(new Eas.WebCrawler.Interfaces.UrlCompletedEventArgs(state, state.ResponseStore)).Will(action);
        }

        public static Uri CreateUri(Eas.WebCrawler.Common.Test.TestDirectory directory, string filename) {
            return new Uri("file://" + directory.CreateFileName(filename));
        }
    }

}
